import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:jump_scape/js_ui/js_widget/js_image_view.dart';

class GameController {
  VoidCallback? restart; // 重新开始
  VoidCallback? pause; // 暂停
  VoidCallback? resume; // 继续

  void restartGame() {
    restart?.call();
  }

  void pauseGame() {
    pause?.call();
  }

  void resumeGame() {
    resume?.call();
  }
}

class SimpleRunningGame extends StatefulWidget {
  final GameController controller;
  final VoidCallback onGameOver;
  const SimpleRunningGame({required this.controller, required this.onGameOver});
  @override
  _SimpleRunningGameState createState() => _SimpleRunningGameState();
}

class _SimpleRunningGameState extends State<SimpleRunningGame> {
  static final speedInit = 1.r; // 每次增加的速度

  static final double playerLeft = 31.r; // 小人左侧距离
  static final double playerSize = 98.r; // 小人尺寸

  final double groundHeight = 353.r; // 地板高度

  double playerY = 0; // 小人 Y 轴位置

  bool isJumping = false; // 是否在跳跃
  bool isFalling = false; // 是否在掉落
  bool gameStarted = false; // 是否开始游戏
  bool gameOver = false; // 游戏是否失败

  double speed = speedInit; // 初始速度

  double screenWidth = ScreenUtil().screenWidth; // 屏幕宽度
  double moveX = 0; // 移动的距离

  Random random = Random(); // 随机数

  List<Rect> holes = []; // 坑洞
  int holesScreenCount = -1;

  Timer? _gameTimer;

  @override
  void initState() {
    super.initState();
    _initHoles();

    // 绑定控制器
    widget.controller.restart = _restartGame;
    widget.controller.pause = _pauseGame;
    widget.controller.resume = _resumeGame;
  }

  @override
  void dispose() {
    super.dispose();
    _pauseGame();
  }

  void _startGame(bool isRestart) {
    if (isRestart) {
      setState(() {
        gameStarted = true;
        gameOver = false;
        isJumping = false;
        isFalling = false;
        playerY = 0;
        speed = speedInit;
        moveX = 0;
        holesScreenCount = -1;
        holes.clear();
        _initHoles();
      });
    }

    _gameTimer = Timer.periodic(Duration(milliseconds: 16), (timer) {
      if (gameStarted && !gameOver && !isFalling) {
        _updateData();
        _initHoles();
        _checkCollision();
        setState(() {});
      }
    });
  }

  void _restartGame() {
    _gameTimer?.cancel();
    _startGame(true);
  }

  void _pauseGame() {
    gameStarted = false;
    _gameTimer?.cancel();
  }

  void _resumeGame() {
    gameStarted = true;
    _startGame(false);
  }

  void _updateData() {
    moveX += speed;
    speed = speedInit + 0.1 * sqrt(moveX);
  }

  void _initHoles() {
    final count = moveX ~/ screenWidth;
    if (holesScreenCount == count) return;
    holesScreenCount = count;

    double startX = holes.isEmpty ? 0 : holes[holes.length - 1].left + holes[holes.length - 1].width;
    double endX = moveX + screenWidth * 2;

    if (moveX == 0) {
      startX += playerLeft + playerSize;
    }

    // 添加 新的 坑
    while (startX < endX) {
      double holeWidth = random.nextDouble() * 50.r + 70.r; // 坑的大小
      double holeStart = startX + random.nextDouble() * playerSize * 2 + playerSize;
      // double holeWidth = 30.r; // 坑的大小
      // double holeStart = startX + 30.r;
      holes.add(Rect.fromLTWH(holeStart, 0, holeWidth, groundHeight));
      startX = holeStart + holeWidth;
    }

    // 检查 超出屏幕的 坑
    for (var i = holes.length - 1; i >= 0; i--) {
      final hole = holes[i];
      final endX = hole.left + hole.width;

      // 移除 超出屏幕的 坑
      if (endX < moveX) holes.remove(hole);
    }

    // debugPrint('[game] 🕳️ holes=${holes.length}, startX=$startX, endX=$endX');
  }

  void _checkCollision() {
    double playerCenter = playerLeft + playerSize / 2;

    for (var hole in holes) {
      double holeLeft = hole.left - moveX;
      double holeRight = hole.right - moveX;

      if (holeLeft < playerCenter && playerCenter < holeRight) {
        if (playerY == 0) {
          // debugPrint('[game] 🥀 playerCenter=$playerCenter, holeLeft=$holeLeft, holeRight=$holeRight');
          _triggerFallAnimation();
          break;
        } else {
          // debugPrint('[game] 🌹 playerCenter=$playerCenter, holeLeft=$holeLeft, holeRight=$holeRight');
        }
      }
    }
  }

  void _triggerFallAnimation() {
    isFalling = true;

    Timer.periodic(Duration(milliseconds: 10), (timer) {
      if (!gameStarted) return;

      playerY -= 10.r;
      if (playerY <= -groundHeight) {
        timer.cancel();
        gameOver = true;
        _gameTimer?.cancel();
        widget.onGameOver(); // 触发失败回调
      }

      setState(() {});
    });
  }

  void _jump() {
    if (!isJumping && playerY == 0 && gameStarted && !gameOver && !isFalling) {
      isJumping = true;

      double initialY = playerY;
      double peakY = playerY + playerSize;

      Timer.periodic(Duration(milliseconds: 16), (timer) {
        if (!gameStarted) return;

        playerY += speed;
        setState(() {});

        if (playerY >= peakY) {
          timer.cancel();

          Timer.periodic(Duration(milliseconds: 16), (downTimer) {
            if (!gameStarted) return;

            playerY -= speed;
            if (playerY <= initialY) {
              playerY = initialY;
              isJumping = false;
              downTimer.cancel();
            }
            setState(() {});
          });
        }
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _jump,
      child: Container(
        width: double.infinity,
        height: double.infinity,
        color: Colors.transparent,
        child: Stack(
          children: [
            // 地板
            Positioned(
              bottom: 0,
              child: CustomPaint(
                size: Size(screenWidth, groundHeight),
                painter: GroundPainter(holes, moveX),
              ),
            ),
            // 小人
            Positioned(
              left: 50.r,
              bottom: groundHeight + playerY,
              child: Container(
                width: playerSize,
                height: playerSize,
                child: jsImage('assets/image/ic_game_ren.png'),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class GroundPainter extends CustomPainter {
  final List<Rect> holes;
  final double moveX;
  final screenWidth = ScreenUtil().screenWidth;

  final fillPaint = Paint()..style = PaintingStyle.fill;
  final borderPaint = Paint()
    ..color = Color.fromARGB(255, 212, 216, 224)
    ..style = PaintingStyle.stroke
    ..strokeWidth = 1.r;
  Paint shadowPaint = Paint()
    ..color = Color(0xFFe3ebf4)
    ..maskFilter = MaskFilter.blur(BlurStyle.inner, 4.r);

  // 扩展部分
  Paint trapezoidPaint = Paint()
    ..color = Color.fromARGB(255, 234, 232, 232)
    ..style = PaintingStyle.fill;
  Paint shadowTrapezoidPaint = Paint()
    ..color = Color(0xFFd5dae4)
    ..maskFilter = MaskFilter.blur(BlurStyle.inner, 4.r);

  GroundPainter(this.holes, this.moveX);

  @override
  void paint(Canvas canvas, Size size) {
    final length = holes.length;
    double lastHoleRight = 0;

    for (var i = 0; i < length; i++) {
      final hole = holes[i];

      double holeLeft = hole.left - moveX;
      double holeRight = hole.right - moveX;
      double holeWidh = hole.width;

      if (0 <= holeRight && holeLeft <= screenWidth) {
        // debugPrint('[game] 🧱 i=$i, length=$length, moveX=${moveX.toInt()}, left=${holeLeft.toInt()}, holeWidh=${holeWidh.toInt()}, hole=$hole');

        // 墙体
        if (holeLeft > 0) {
          final previousHole = i == 0 ? null : holes[i - 1];

          double wallLeft = previousHole == null ? 0 : previousHole.right - moveX;
          double wallRight = hole.left - moveX;

          drawWall(canvas, size, wallLeft, wallRight);
        }

        //  坑
        // fillPaint.color = Colors.black.withOpacity(0.4);
        // canvas.drawRect(Rect.fromLTWH(holeLeft, 0, holeWidh, size.height), fillPaint);

        // final textStyle = TextStyle(color: Colors.white, fontSize: 24);
        // final textSpan = TextSpan(text: '${hole.width.toInt()}', style: textStyle);
        // final textPainter = TextPainter(text: textSpan, textDirection: TextDirection.ltr);
        // textPainter.layout(maxWidth: holeWidh);
        // final offset = Offset(holeLeft, (size.height - textPainter.height) / 2);
        // textPainter.paint(canvas, offset);

        lastHoleRight = holeRight;
      }
    }

    // 墙体
    if (lastHoleRight <= screenWidth) {
      drawWall(canvas, size, lastHoleRight, screenWidth);
    }
  }

  void drawWall(Canvas canvas, Size size, double left, double right) {
    fillPaint.color = Color(0xFFFCFCFC);

    // 梯形
    Path trapezoidPath = Path()
      ..moveTo(right - 2.r, 0)
      ..lineTo(right - 2.r + 26.r, 21.r)
      ..lineTo(right - 2.r + 26.r, size.height)
      ..lineTo(right - 2.r, size.height)
      ..close();

    // 梯形 - 内部
    canvas.drawPath(trapezoidPath, trapezoidPaint);
    // 梯形 - 阴影
    canvas.drawPath(trapezoidPath, shadowTrapezoidPaint);
    // 梯形 - 边框
    canvas.drawPath(trapezoidPath, borderPaint);

    final rect = Rect.fromLTRB(left, 0, right, size.height);
    RRect roundedRect = RRect.fromRectAndCorners(rect, topLeft: Radius.circular(3.r), topRight: Radius.circular(3.r));
    // 矩形 - 内部
    canvas.drawRRect(roundedRect, fillPaint);
    // 矩形 - 阴影
    canvas.drawRRect(roundedRect, shadowPaint);
    // 矩形 - 边框
    canvas.drawRRect(roundedRect, borderPaint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
}
